package com.zcily.demo.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zcily.demo.model.entity.User;
import com.zcily.demo.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Api(tags = "首页控制器")
@RestController
@Slf4j
public class IndexController {

    @Resource
    private UserService userService;

    // 登录  ---- http://localhost:6710
    @ApiOperation("首页")
    @GetMapping(value = {"", "/"})
    @SaIgnore
    public String index() {
        return "Hello World!";
    }

    // 登录  ---- http://localhost:6710/login?username=xy_zc&password=123456
    @ApiOperation("登录")
    @GetMapping("/login")
    @SaIgnore
    public SaResult login(@RequestParam String username, @RequestParam String password) {
        if (StpUtil.isLogin()) {
            return SaResult.ok("用户已登录");
        }

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        User user = userService.getOne(wrapper);
        if (user == null) {
            return SaResult.error("登录失败");
        }

        if (user.getPassword().equals(password)) {
            StpUtil.login(user.getId());

            // 获取当前登录账号的专属 SaSession 对象
            // 注意点1：只有登录后才可以调用这个方法
            // 注意点2：每个账号获取到的都是不同的 SaSession 对象，存取值时不会互相影响
            // 注意点3：SaSession 和 HttpSession 是两个完全不同的对象，不可混淆使用
            SaSession session = StpUtil.getSession();
            session.set("user", user);

            List<String> permissions = new ArrayList<>();
            userService.selectUserPermissions(user.getId()).forEach(item -> {
                if (StringUtils.isNotBlank(item.getPerms())) {
                    permissions.addAll(Arrays.asList(item.getPerms().split(",")));
                }
            });
            session.set("permissions", permissions);

            List<String> roles = new ArrayList<>();
            userService.selectUserRoles(user.getId()).forEach(item -> {
                if (StringUtils.isNotBlank(item.getRoleCode())) {
                    roles.add(item.getRoleCode());
                }
            });
            session.set("roles", roles);

            return SaResult.ok("登录成功");
        }

        return SaResult.error("登录失败");
    }

    // 查询用户登录状态  ---- http://localhost:6710/loginStatus
    @ApiOperation("查询用户登录状态")
    @GetMapping("/loginStatus")
    @SaIgnore
    public SaResult loginStatus() {
        return SaResult.data(StpUtil.isLogin());
    }

    // 登出  ---- http://localhost:6710/logout
    @ApiOperation("登出")
    @GetMapping("/logout")
    @SaIgnore
    public SaResult logout() {
        StpUtil.logout();
        return SaResult.ok();
    }

    // 查询登录用户的信息  ---- http://localhost:6710/my/info
    @ApiOperation("查询登录用户的信息")
    @GetMapping("/my/info")
    public SaResult myInfo() {
        // 获取当前登录账号的专属 SaSession 对象
        // 注意点1：只有登录后才可以调用这个方法
        // 注意点2：每个账号获取到的都是不同的 SaSession 对象，存取值时不会互相影响
        // 注意点3：SaSession 和 HttpSession 是两个完全不同的对象，不可混淆使用
        SaSession session = StpUtil.getSession();
        return SaResult.data(session.get("user"));
    }

    // 查询登录用户的 Token 信息  ---- http://localhost:6710/my/token
    @ApiOperation("查询登录用户的 Token 信息")
    @GetMapping("/my/token")
    public SaResult token() {
        return SaResult.data(StpUtil.getTokenInfo());
    }

    // 查询登录用户的权限  ---- http://localhost:6710/my/authorization
    @ApiOperation("查询登录用户的权限")
    @GetMapping("/my/authorization")
    public SaResult myAuthorization() {
        // 查询权限信息 ，如果当前会话未登录，会返回一个空集合
        List<String> permissionList = StpUtil.getPermissionList();
        System.out.println("当前登录账号拥有的所有权限：" + permissionList);

        // 查询角色信息 ，如果当前会话未登录，会返回一个空集合
        List<String> roleList = StpUtil.getRoleList();
        System.out.println("当前登录账号拥有的所有角色：" + roleList);

        // 返回给前端
        return SaResult.ok().set("roles", roleList).set("permissions", permissionList);
    }
}
